package org.altoro.trongeventquery.blocks;

import com.alibaba.fastjson.JSONObject;
import org.altoro.trongeventquery.query.QueryFactory;
import org.altoro.trongeventquery.transactions.TransactionTriggerEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@Component
public class BlockController {
    @Autowired(required = false)
    MongoTemplate mongoTemplate;

    @RequestMapping(method = RequestMethod.GET, value = "/blocks/total")
    public Long totalblock() {
        QueryFactory query = new QueryFactory();
        long number = mongoTemplate.count(query.getQuery(), BlockTriggerEntity.class);
        return number;
    }

    @RequestMapping(method = RequestMethod.GET, value = "/blocks/new")
    public BlockTriggerEntity newBlock() {
        QueryFactory query = new QueryFactory();
        query.setSort(new Sort(Sort.Direction.DESC, "timeStamp"));
        return mongoTemplate.findOne(query.getQuery(), BlockTriggerEntity.class);
    }

    @RequestMapping(method = RequestMethod.GET, value = "/blocks")
    public JSONObject getBlocks(
            /******************* Page Parameters ****************************************************/
            @RequestParam(value = "limit", required = false, defaultValue = "15") int limit,
            @RequestParam(value = "sort", required = false, defaultValue = "-timeStamp") String sort,
            @RequestParam(value = "start", required = false, defaultValue = "0") int start,
            /****************** Filter parameters *****************************************************/
            @RequestParam(value = "block", required = false, defaultValue = "-1") long block
    ) {
        QueryFactory query = new QueryFactory();
        if (block > 0) {
            query.setBlockNumGte(block);
        }
        query.setPageniate(QueryFactory.setPagniateVariable(start, limit, sort));
        List<BlockTriggerEntity> queryResult = mongoTemplate.find(query.getQuery(),
                BlockTriggerEntity.class);
        Map map = new HashMap();

        QueryFactory queryTotal = new QueryFactory();
        if (block > 0) {
            queryTotal.setBlockNumGte(block);
        }
        map.put("total", mongoTemplate.count(queryTotal.getQuery(), BlockTriggerEntity.class));
        map.put("size", queryResult.size());
        map.put("data", queryResult);
        return new JSONObject(map);
    }

    @RequestMapping(method = RequestMethod.GET, value = "/blocks/{hash}")
    public JSONObject getBlockbyHash(
            @PathVariable String hash
    ) {

        QueryFactory query = new QueryFactory();
        query.setBlockHashEqual(hash);
        List<BlockTriggerEntity> queryResult = mongoTemplate.find(query.getQuery(),
                BlockTriggerEntity.class);
        if (queryResult.size() == 0) {
            return null;
        }

        BlockTriggerEntity blockTriggerEntity = queryResult.get(0);
        if (blockTriggerEntity.getTransactionList().size() > 0) {
            List<TransactionTriggerEntity> transactionTriggerList = new ArrayList<>();
            for (String s : blockTriggerEntity.getTransactionList()) {
                QueryFactory TransactionQuery = new QueryFactory();
                TransactionQuery.setTransactionIdEqual(s);
                TransactionTriggerEntity transactionTriggerEntity = mongoTemplate.findOne(TransactionQuery.getQuery(), TransactionTriggerEntity.class);
                transactionTriggerList.add(transactionTriggerEntity);
            }
            blockTriggerEntity.setTransactionTriggerList(transactionTriggerList);
        }

        Map map = new HashMap();
        map.put("block", blockTriggerEntity);

        return new JSONObject(map);
    }

    @RequestMapping(method = RequestMethod.GET, value = "/blocks/latestSolidifiedBlockNumber")
    public long getLatestSolidifiedBlockNumber() {
        QueryFactory query = new QueryFactory();
        query.setPageniate(QueryFactory.setPagniateVariable(0, 1, "-latestSolidifiedBlockNumber"));
        List<BlockTriggerEntity> blockTriggerEntityList = mongoTemplate.find(query.getQuery(),
                BlockTriggerEntity.class);
        if (blockTriggerEntityList.isEmpty()) {
            return 0;
        }
        return blockTriggerEntityList.get(0).getLatestSolidifiedBlockNumber();
    }
}
